package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.face.AipFaceTemplate;
import com.itheima.autoconfig.huanxin.HuanXinTemplate;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.autoconfig.sms.SmsTemplate;
import com.itheima.domain.db.*;
import com.itheima.domain.mongo.Friend;
import com.itheima.domain.mongo.RecommendUser;
import com.itheima.domain.vo.*;
import com.itheima.service.db.NotificationService;
import com.itheima.service.db.QuestionService;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.service.mongo.FriendService;
import com.itheima.service.mongo.RecommendUserService;
import com.itheima.service.mongo.UserLikeService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.Jedis;

import java.io.IOException;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class UserManager {

    @Reference
    private UserService userService;

    //保存用户,返回主键
    public Long save(User user) {
        //1.给用户密码加密
        String md5pwd = SecureUtil.md5(user.getPassword());
        //2.设置加密后的密码
        user.setPassword(md5pwd);
        //3.执行保存用户操作
        Long id = userService.save(user);
        //4.返回主键
        return id;
    }

    //根据手机号查询用户
    public User findByPhone(String phone) {
        return userService.findByPhone(phone);
    }

    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //发送验证码
    public void sendSms(String phone) {
        /*//1.生成随机验证码
        String code = String.valueOf(RandomUtil.randomNumbers(6));
        //2.发送验证码
        smsTemplate.sendSms(phone, code);
        //将验证码存入redis
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE+phone,code, Duration.ofMinutes(5));
        */
        //将验证码存入redis,超时五分钟之后消失
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE + phone, "123456", Duration.ofMinutes(5));
        Jedis jedis = new Jedis ("192.168.136.160", 6379);
        jedis.select (1);
        //判断该手机号是否被冻结
        String value = jedis.get (ConstantUtil.FREEZE_USER + phone);
        if (value != null) {
            throw new RuntimeException ("该用户登录已被封禁");
        }

    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    //登录或者注册
    public Map regOrLogin(String phone, String verificationCode) {
        //创建日志对象
        Log log = new Log();
        //获取redis中的验证码
        String code = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);
        //标志位,标识该用户是否为新用户
        boolean isNew = false;
        //比较验证码是否正确
        if (!StrUtil.equals(verificationCode, code)) {
            //不相等,抛出异常

            throw new RuntimeException(ConstantUtil.CODE_MESSAGE);
        }
        stringRedisTemplate.delete(ConstantUtil.SMS_CODE + phone);
        //对比成功,根据手机号查询用户
        User user = findByPhone(phone);
        //如果user为null,执行注册操作
        if (user == null) {
            user = new User();
            user.setPhone(phone);
            user.setPassword(ConstantUtil.INIT_PASSWORD);
            Long id = save(user);
            //设置id的目的时后续构建token时需要使用
            user.setId(id);
            isNew = true;
            //向环信中注册用户,为了后面的聊天操作
            huanXinTemplate.register(id);
            log.setType("0102");
        } else {
            isNew = false;
            log.setType("0101");
        }
        //设置log属性
        log.setEquipment("华为nova2s");
        log.setPlace("北京");
        log.setUserId(user.getId());
        log.setLogTime(DateUtil.today());
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getId());
        map.put("phone", user.getPhone());

        //发送MQ消息,进行日志保存
        rocketMQTemplate.convertAndSend("tanhua-log-161" , log);

        String token = JwtUtil.createToken(map);
        //将token存入redis 主要是存入用户的登录状态 (所有的登陆信息 在token中)  此时的值 无所谓   , 设置过期的时间

        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, "1", Duration.ofDays(7));
        //构建返回数据
        Map<Object, Object> resultMap = new HashMap<>();
        resultMap.put("token", token);
        resultMap.put("isNew", isNew);
        return resultMap;
    }

    @Reference
    private UserInfoService userInfoService;

    //保存用户个人信息
    public void saveUserInfo(UserInfo userInfo) {
        //默认数据
        userInfo.setTags("单身,本科,年龄相仿"); //这个是必须给的
        userInfo.setAge(18);
        userInfo.setProfession("计算机");
        userInfo.setIncome("30");
        userInfo.setMarriage(1);
        userInfoService.save(userInfo);
    }

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    @Autowired
    private OssTemplate ossTemplate;

    //上传头像
    public void uploadHeader(MultipartFile headPhoto, Long id) throws IOException {
        //System.out.println("上传头像");
        //1.人脸识别
        boolean flag = aipFaceTemplate.detect(headPhoto.getBytes());
        //如果识别成功
        if (flag) {
            System.out.println("上传图片");
            //上传图片
            String path = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
            UserInfo userInfo = new UserInfo();
            userInfo.setId(id);
            userInfo.setCoverPic(path);
            userInfo.setAvatar(path);
            userInfoService.update(userInfo);
        }
    }

    //根据id查询用户信息
    public UserInfoVo findByUser(Long id) {
        UserInfo userInfo = userInfoService.findById(id);
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtil.copyProperties(userInfo, userInfoVo);
        return userInfoVo;
    }

    //修改个人信息
    public void updateUserInfo(UserInfo userInfo) {
        userInfoService.update(userInfo);
    }

    @Reference
    private QuestionService questionService;

    @Reference
    private NotificationService notificationService;

    //查询用户通用设置
    public SettingVo findSettings(User user) {
        Question question = questionService.findByUserId(user.getId());
        Notification notification = notificationService.findByUserId(user.getId());
        SettingVo settingVo = new SettingVo();
        settingVo.setId(user.getId());
        settingVo.setPhone(user.getPhone());
        if (question == null) {
            settingVo.setStrangerQuestion("???");
        } else {
            settingVo.setStrangerQuestion(question.getStrangerQuestion());
        }
        if (notification == null) {
            settingVo.setPinglunNotification(false);
            settingVo.setLikeNotification(false);
            settingVo.setGonggaoNotification(false);
        } else {
            settingVo.setGonggaoNotification(notification.getGonggaoNotification());
            settingVo.setLikeNotification(notification.getPinglunNotification());
            settingVo.setPinglunNotification(notification.getLikeNotification());
        }

        return settingVo;
    }

    @Reference
    private UserLikeService userLikeService;

    /**
     * 查询用户相互喜欢/喜欢/粉丝数
     *
     * @return
     */
    public UserLikeCountVo userLikeCount() {
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        //查询相互喜欢数
        Long eachLoveCount = userLikeService.eachLoveCount(loginUserId);
        //查询喜欢数
        Long loveCount = userLikeService.LoveCount(loginUserId);
        //查询粉丝数
        Long fanCount = userLikeService.fanCount(loginUserId);
        //封装UserLikeCountVo对象
        UserLikeCountVo likeCountVo = new UserLikeCountVo();
        likeCountVo.setEachLoveCount(eachLoveCount);
        likeCountVo.setLoveCount(loveCount);
        likeCountVo.setFanCount(fanCount);
        return likeCountVo;
    }

    @Reference
    private RecommendUserService recommendUserService;

    /**
     * 查询相互喜欢/喜欢/粉丝/谁看过我详细信息
     *
     * @param page     页码
     * @param pageSize 每页条数
     * @param type     类型
     * @return
     */
    public PageBeanVo finUserInfoByType(Integer page, Integer pageSize, String type) {
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        //根据type类型去判断查询哪张表
        PageBeanVo pageBeanVo = userLikeService.findUserListByType(page, pageSize, loginUserId, type);
        List<UserLikeVo> items = (List<UserLikeVo>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(items)) {
            for (UserLikeVo item : items) {
                //查询用户个人信息
                UserInfo userInfo = userInfoService.findById(item.getId());
                //将数据转移到userLikeVo对象中
                BeanUtil.copyProperties(userInfo, item);
                //处理缘分值
                RecommendUser fateValue = recommendUserService.findFateValue(loginUserId, item.getId());
                item.setMatchRate(fateValue.getScore().intValue());
                //处理是否已经喜欢
                item.setAlreadyLove(userLikeService.likeEachOther(loginUserId, item.getId()));
            }
        }

        //如果操作是谁看过我,重新设置登录时间
        if (StrUtil.equals(type, "4")) {
            stringRedisTemplate.opsForValue().set(ConstantUtil.LAST_ACCESS_TIME + loginUserId, System.currentTimeMillis() + "");
        }
        return pageBeanVo;
    }

    @Reference
    private FriendService friendService;

    /**
     * 喜欢粉丝
     *
     * @param fanId 粉丝id
     */
    public void saveLikeFan(Long fanId) {
        System.out.println("喜欢粉丝");
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        userLikeService.saveUserLike(fanId, loginUserId);
        //喜欢粉丝之后,将他加到朋友列表里面
        friendService.addContact(loginUserId, fanId);
        //环新里面也添加好友
        huanXinTemplate.addContacts(loginUserId, fanId);
    }


    /**
     * 取消喜欢用户
     *
     * @param userId 用户id
     */
    public void deleteLikeUser(Long userId) {
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        //查询是否相互喜欢
        boolean flag = userLikeService.likeEachOther(loginUserId, userId);
        //如果相互喜欢,删除双方的好友关系
        if (flag) {
            friendService.deleteFriend(loginUserId, userId);
            huanXinTemplate.deleteContacts(loginUserId, userId);
        }
        //删除对他的喜欢
        userLikeService.deleteUserLike(loginUserId, userId);

    }
}
